#include <stdbool.h>
// Lnode是普通节点
// LinkList是链表头指针类型

typedef struct LNode
{
    // 数据域
    int data;
    // 指针域
    struct LNode *next;
} LNode, *LinkList;
/**
 * @brief 初始化链表
 * @param LinkList *L 链表头指针地址
 * @return 初始化成功返回true，否则返回false。
 */
bool InitList_LinkList(LinkList *L);

/**
 * @brief 判断链表是不是空的
 * @param LinkList L
 * 如果没有需要的返回值，又需要将修改的结果带出来就可以使用指针
 * @return true 空链表，false 非空链表。
 */
bool ListEmpty_LinkList(LinkList L);
/**
 * @brief 获得链表的长度
 * @details 遍历链表，计算长度。
 * @param LinkList L 链表头指针。
 * @return 链表长度。
 */
int ListLength_LinkList(LinkList L);
/**
 * @brief 获取链表第pos个元素的值
 * @param LinkList L 链表头指针。
 * @return int elem 元素值。
 * @return true 成功，false 失败。
 */
bool GetElem_LinkList(LinkList L, int pos, int *elem);

/**
 * @brief 按照值查找元素位置
 * @param LinkList L 链表头指针。
 * @param int e 元素值。
 * @return 返回节点的地址。
 */
LNode *LocalElem_LinkList(LinkList L, int elem);
/**
 * @brief 前插法插入元素（所以前插法不是插入到前一个节点，
 * 而是插入到前一个节点的后面，从而成为新的第 pos 个节点。）
 * @param LinkList *L 链表头指针地址，使用二级指针来直接修改头指针
 * @return true 插入成功，false 插入失败。
 */
bool InsertElem(LinkList *L, int pos, int elem);
/**
 * @brief 删除元素
 * @param LinkList *L 链表头指针地址，使用二级指针来直接修改头指针
 * @return true 删除成功，false 删除失败。
 */
bool DeleteElem(LinkList *L, int pos, int *elem);
/**
 * @brief 打印列表
 * @param
 * @return
 */
void PrintList_LinkList(LinkList L);
/**
 * @brief 销毁列表
 * @param
 * @return
 */
void DestoryList(LinkList *L);
/**
 * @brief 使用头插法创建链表
 * @details 头插法其实就是一直以头节点为基础，将新的节点插入到头节点后面，从而形成新的链表。
 * @param
 * @return
 */
void CreateListHead(LinkList *L, int n);
/**
 * @brief 使用尾插法创建链表
 * @details 尾插法其实是一直将新节点的数据域设置为null，
 * 然后使用一个尾指针，将新节点插入到尾指针的后面。
 * 其实就是将新节点的地址赋值给尾指针的指针域，
 * 让后在让尾指针直接指向新节点。
 * @param
 *
 * @return
 */
void CreateListTail(LinkList *L, int n);